package com.jt.service;

import com.jt.vo.ImageVO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.security.DigestInputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

@Service
@PropertySource("classpath:/properties/image.properties")
public class FiledServiceImpl implements FiledService {
    @Value("${image.pathDir}")
    private String pathDir;
    @Value("${image.urlPath}")
    private String urlPath;
    //为了防止set集合每次都要创建,通过static代码块的形式负责封装数据
    private static Set<String> imageSet = new HashSet<>();

    static {
        imageSet.add(".jpg");
        imageSet.add(".png");
        imageSet.add(".gif");
    }

    /**
     * 文件上传具体操作:
     * 1.如何校验用户上传的是图片           jpg/png
     * 2.如何防止用户上传恶意程序           木马.exe.jpg
     * 3.应该采用分目录存储的方式           保存数据
     * 4.上传的文件名称应该尽量避免重名      自定义文件名称 uuid
     */
    @Override
    public ImageVO upload(MultipartFile uploadFile) {
        //1.校验图片类型是否正确
        //1.1获取上传图片类型
        String fileName = uploadFile.getOriginalFilename();//得到文件全名
        fileName = fileName.toLowerCase();//将所有的字符转化为小写
        int index = fileName.lastIndexOf(".");
        String fileType = fileName.substring(index);//含头不含尾,此处取到 .后缀
        if (!imageSet.contains(fileType)) {
            return ImageVO.fail();
        }
        //2.校验上传的数据是否为恶意程序,高度和宽度是否为null,利用图片API
        //bufferedImage对象,专门用来封装图片
        try {
            BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            if (width == 0 || height == 0) {
                return ImageVO.fail();
            }
            //3.采用分目录存储的方式
            // String pathDir = "D:/photo/jt"; //动态获取本地磁盘存储地址
            //3.1采用时间方式分目录存储
            String dateDir = new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
            //3.2准备文件存储的目录
            String imageDir = pathDir + dateDir;//根目录+时间目录
            File imageFileDir = new File(imageDir);
            if (!imageFileDir.exists()) {
                imageFileDir.mkdirs();//此处创建文件存储的本地目录,包含根目录+时间目录
            }
            //4.实现文件上传
            //4.1动态拼接文件名称       uuid.后缀
            String uuid = UUID.randomUUID().toString().replace("-", "");
            String uuidFileName = uuid + fileType;//uuid.后缀
            //4.2准备文件上传的全路径
            File imageRootFile = new File(imageDir + uuidFileName);
            //4.3实现文件上传
            try {
                uploadFile.transferTo(imageRootFile);
            } catch (IOException e) {
                e.printStackTrace();
                ImageVO.fail();
            }
            //5.动态生成URL
            //请求协议:http://    https:// 带证书的网站,安全系更高
            String url = urlPath + dateDir + uuidFileName;
            return ImageVO.success(url, width, height);
        } catch (
                IOException e) {
            e.printStackTrace();
            return ImageVO.fail();
        }
    }
}

